#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <jsoncpp/json/json.h>

//协议：订制协议 分别提供请求和响应的序列反序列化  并提供编码解码接口

// #define MySelf 1

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

//编码："XXXXXX"len"\n"x op y"\nXXXXXX
std::string Encode(std::string &stringMsg)
{
    // "x op y" -> "len"\n"x op y"\n
    std::string encoded_strMsg = std::to_string(stringMsg.size());
    encoded_strMsg += protocol_sep;
    encoded_strMsg += stringMsg;
    encoded_strMsg += protocol_sep;

    return encoded_strMsg;
}


// 解码："XXXXXX"len"\n"x op y"\nXXXXXX
bool Decode(std::string &encoded_strMsg, std::string *stringMsg)
{
    // "len"\n"x op y"\n -> "x op y"
    std::size_t pos = encoded_strMsg.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
    std::string len_str = encoded_strMsg.substr(0, pos);
    std::size_t len = std::stoi(len_str);
    std::size_t total_len = len_str.size() + len + 2;
    if (encoded_strMsg.size() < total_len)
        return false;

    *stringMsg = encoded_strMsg.substr(pos + 1, len);
    encoded_strMsg.erase(0, total_len);

    return true;
}

// 请求类 struct {x op y} <==> string
class Request
{
public:
    // x op y
    int x;
    int y;
    char op; // + - * / %
public:
    Request(int data1, int data2, char oper)
        : x(data1),
          y(data2),
          op(oper)
    {
    }

    Request()
    {
    }

public:
    // 序列化：数据结构-->字节序列
    bool Serialize(std::string *structed_Data)
    {
#ifdef MySelf
        // 构建报文的有效载荷 struct => string, "x op y"
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *structed_Data = s;
        return true;
#else
        Json::Value root;
        root["x"] = x;
        root["y"] = y;
        root["op"] = op;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *structed_Data = w.write(root);
        return true;
#endif
    }

    // 反序列化：字节序列-->数据结构
    bool Deserialize(const std::string &stringMsg) // "x op y"
    {
#ifdef MySelf
        std::size_t left = stringMsg.find(blank_space_sep);
        if (left == std::string::npos)
            return false;
        std::string part_x = stringMsg.substr(0, left);

        std::size_t right = stringMsg.rfind(blank_space_sep);
        if (right == std::string::npos)
            return false;
        std::string part_y = stringMsg.substr(right + 1);

        if (left + 2 != right)
            return false;
        op = stringMsg[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(stringMsg, root);

        x = root["x"].asInt();
        y = root["y"].asInt();
        op = root["op"].asInt();
        return true;
#endif
    }

    // 测试打印
    void DebugPrint()
    {
        std::cout << "新请求构建完成:  " << x << op << y << "=?" << std::endl;
    }
};

// 响应类：result code <==> "result code"
class Response
{
public:
    int _result;
    int _code; // 0正确; 非0表明对应的错误原因
public:
    Response(int result, int code)
        : _result(result),
          _code(code)
    {
    }

    Response()
    {
    }

public:
    //result code --> "result code"
    bool Serialize(std::string *structedData)
    {
#ifdef MySelf
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *structedData = s;
        return true;
#else
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *structedData = w.write(root);
        return true;
#endif
    }
    // "result code"-->result code
    bool Deserialize(const std::string &stringMsg) 
    {
#ifdef MySelf
        std::size_t pos = stringMsg.find(blank_space_sep);
        if (pos == std::string::npos)
            return false;
        std::string part_left = stringMsg.substr(0, pos);
        std::string part_right = stringMsg.substr(pos + 1);

        result = std::stoi(part_left);
        code = std::stoi(part_right);

        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(stringMsg, root);

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
#endif
    }

    void DebugPrint()
    {
        std::cout << "结果响应完成 result: " << _result << " code: " << _code << std::endl;
    }
};